package com.ma.chapter4.t3;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Vector;

/**
 * 买票卖票线程安全分析
 */
@Slf4j(topic = "m.TicketSellTest")
public class ExerciseSell {

    static Random random = new Random();

    public static int randomAmount() {
        //生成 [1,6) 的随机整数
        return random.nextInt(5) + 1;
    }

    public static void main(String[] args) {
        TicketWindow ticketWindow = new TicketWindow(2000);
        //所有线程（购票人）的集合
        List<Thread> list = new ArrayList<>();
        //卖出去多少票
        List<Integer> sellCount = new Vector<>();

        for (int i = 0; i < 2000; i++) {
            Thread t = new Thread(() -> {
                //分析这里的竟态条件
                //sell方法内部有对共享变量的读写操作
                int sell = ticketWindow.sell(randomAmount());
                sellCount.add(sell);
            });
            list.add(t);
            t.start();
        }
        //等待所有人买完票
        list.forEach((t) -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        //卖出去的票求和
        int sum = sellCount.stream().mapToInt(c -> c).sum();
        int count = ticketWindow.getCount();
        log.debug("sell count = {}",sum);
        log.debug("remainder count = {}",count);

    }
}

/**
 * 车站窗口类
 */
class TicketWindow {
    private int count;

    public TicketWindow(int count) {
        this.count = count;
    }

    public int getCount() {
        return count;
    }

    public synchronized int sell(int amount) {
        if (this.count > amount) {
            this.count -= amount;
            return amount;
        } else {
            return 0;
        }

    }
}